﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using UnityEngine;

namespace NinjaToolbox.SubComponentModule
{
    public class SubComponentMonoContainer : MonoBehaviour, ISerializationCallbackReceiver
    {
        SubComponentContainer mSubComponentContainer = new SubComponentContainer();

        [SerializeField]
        ComponentSerializeUnion[] mSerializeDataArray;


        public void AddSubComponent(SubComponentBase subComponent)
        {
            mSubComponentContainer.AddSubComponent(subComponent, enumerator => StartCoroutine(enumerator));
        }

        public bool RemoveSubComponent(SubComponentBase subComponent)
        {
            return mSubComponentContainer.RemoveSubComponent(subComponent);
        }

        public T GetSubComponent<T>()
            where T : SubComponentBase
        {
            return mSubComponentContainer.GetSubComponent<T>();
        }

        public T[] GetSubComponents<T>()
            where T : SubComponentBase
        {
            return mSubComponentContainer.GetSubComponents<T>();
        }

        void Awake()
        {
            var context = new SubComponentContext() { Container = mSubComponentContainer, Owner = this };
            mSubComponentContainer.Initialization(context, (enumerator) => StartCoroutine(enumerator));

            mSubComponentContainer.DoAwake();
        }

        void OnEnable()
        {
            mSubComponentContainer.DoOnEnable();
        }

        void Start()
        {
            mSubComponentContainer.DoStart();
        }

        void OnDisable()
        {
            mSubComponentContainer.DoOnDisable();
        }

        void OnDestroy()
        {
            mSubComponentContainer.DoOnDestroy();
        }

        void Update()
        {
            mSubComponentContainer.DoUpdate();
        }

        void FixedUpdate()
        {
            mSubComponentContainer.DoFixedUpdate();
        }

        void LateUpdate()
        {
            mSubComponentContainer.DoLateUpdate();
        }

        void ISerializationCallbackReceiver.OnBeforeSerialize()
        {
            mSerializeDataArray = mSubComponentContainer.SerializeToUnion();
        }

        void ISerializationCallbackReceiver.OnAfterDeserialize()
        {
            if (mSerializeDataArray != null)
            {
                mSubComponentContainer.DeserializeFromUnion(mSerializeDataArray);
                mSerializeDataArray = null;
            }
        }
    }
}
